package com.atguigu.gulimall.order.service.impl;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.exception.NoStockException;
import com.atguigu.common.to.mq.OrderTo;
import com.atguigu.common.to.mq.SeckillOrderTo;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberEntity;
import com.atguigu.gulimall.order.config.PayVo;
import com.atguigu.gulimall.order.constant.OrderConstant;
import com.atguigu.gulimall.order.dao.OrderItemDao;
import com.atguigu.gulimall.order.entity.OrderItemEntity;
import com.atguigu.gulimall.order.entity.PaymentInfoEntity;
import com.atguigu.gulimall.order.enume.OrderStatusEnum;
import com.atguigu.gulimall.order.feign.CartFeignService;
import com.atguigu.gulimall.order.feign.MemberFeignService;
import com.atguigu.gulimall.order.feign.WmsFeignService;
import com.atguigu.gulimall.order.interceptor.LoginUserInterceptor;
import com.atguigu.gulimall.order.service.OrderItemService;
import com.atguigu.gulimall.order.service.PaymentInfoService;
import com.atguigu.gulimall.order.to.OrderCreateTo;
import com.atguigu.gulimall.order.vo.*;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import javafx.beans.property.BooleanProperty;
import org.aspectj.weaver.ast.Or;
import org.bouncycastle.asn1.x509.qualified.BiometricData;
import org.bouncycastle.math.Primes;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitRetryTemplateCustomizer;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.channels.MulticastChannel;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.order.dao.OrderDao;
import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    private ThreadLocal<OrderSubmitVo>  confirmVoThreadLocal  =     new ThreadLocal<>();
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private ProductFeignService productFeignService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CartFeignService cartFeignService;
    @Autowired
    private WmsFeignService wmsFeignService;
    @Autowired
    private MemberFeignService memberFeignService;
    @Autowired
    private ThreadPoolExecutor executor;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );
        return new PageUtils(page);
    }
    /*
    返回订单确认页需要用的数据
     */
    @Override
    public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        MemberEntity member = LoginUserInterceptor.loginUser.get();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<MemberAddressVo> addresses = memberFeignService.getAddresses(member.getId());
            orderConfirmVo.setAddress(addresses);
        }, executor);
        CompletableFuture<Void> cartFuture = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<OrderItemVo> orderItemVos = cartFeignService.currentUserCartItems();
            orderConfirmVo.setItems(orderItemVos);
        }, executor).thenRunAsync( () -> {
            List<OrderItemVo> items = orderConfirmVo.getItems();
            List<Long> collect = items.stream().map(item -> {
                return item.getSkuId();
            }).collect(Collectors.toList());
            R skusHasStock = wmsFeignService.getSkusHasStock(collect);
            List<SkuStockVo> data = skusHasStock.getData(new TypeReference<List<SkuStockVo>>() {
            });
            if (data != null) {
                Map<Long, Boolean> map = data.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
                orderConfirmVo.setStocks(map);
            }
        },executor);
        Integer integration = member.getIntegration();
        orderConfirmVo.setIntegration(integration);
        String token = UUID.randomUUID().toString().replace("-", "");
        stringRedisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX+member.getId(),token,30, TimeUnit.MINUTES);
        orderConfirmVo.setOrderToken(token);
        CompletableFuture.allOf(getAddressFuture,cartFuture).get();
        return orderConfirmVo;
    }
    @Override
    public OrderConfirmVo confirmOrder2() {
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo(); //   构建对象:订单确认页需要的数据的对象
        MemberEntity member = LoginUserInterceptor.loginUser.get();  //  获取当前登录用户
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); //   这个是什么?
        RequestContextHolder.setRequestAttributes(requestAttributes);  //这个又是什么?
        List<MemberAddressVo> addresses = memberFeignService.getAddresses(member.getId());  //  获取
        orderConfirmVo.setAddress(addresses);
        RequestContextHolder.setRequestAttributes(requestAttributes);
        List<OrderItemVo> orderItemVos = cartFeignService.currentUserCartItems();
        orderConfirmVo.setItems(orderItemVos);
        List<OrderItemVo> items = orderConfirmVo.getItems();
        List<Long> collect = items.stream().map(item -> {
            return item.getSkuId();
        }).collect(Collectors.toList());
        R skusHasStock = wmsFeignService.getSkusHasStock(collect);
        List<SkuStockVo> data = skusHasStock.getData(new TypeReference<List<SkuStockVo>>() {
        });
        if (data != null) {
            Map<Long, Boolean> map = data.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
            orderConfirmVo.setStocks(map);
        }
        Integer integration = member.getIntegration();
        orderConfirmVo.setIntegration(integration);
        String token = UUID.randomUUID().toString().replace("-", "");// 生成了一个token
        stringRedisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX+member.getId(),token,30, TimeUnit.MINUTES);// 把token放在redis中,
        orderConfirmVo.setOrderToken(token);//然后把token给用户
        return orderConfirmVo;
    }
    /*
    获取当前订单的支付信息
     */
    @Override
    public PayVo getOrderPay(String orderSn) {
        PayVo payVo = new PayVo();    
        OrderEntity orderEntity=this.getOrderByOrderSn(orderSn);  //  返回一个主表对象
        BigDecimal totalAmount = orderEntity.getTotalAmount();  //  取值
        BigDecimal bigDecimal = totalAmount.setScale(2, RoundingMode.UP);  // 取值
        payVo.setTotal_amount(bigDecimal.toString()); // 赋值
        payVo.setOut_trade_no(orderEntity.getOrderSn());//  赋值
        List<OrderItemEntity> orderItemEntityList = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderSn)); //  去数据查订单项表:oms_order_item
        OrderItemEntity orderItemEntity = orderItemEntityList.get(0);   //   把订单的第一个sku取出来
        payVo.setSubject(orderItemEntity.getSkuName());  //  把订单的第一个sku的sku名字 设置成订单名称
        payVo.setBody(orderItemEntity.getSkuAttrsVals());//  把订单的第一个sku的销售属性设置成订单商品描述
        return  payVo;  //   返回订单主要信息对象,这个是调用支付宝的时候用到
    }
    @Override
    public PageUtils queryPageWithItem(Map<String, Object> params) {
        MemberEntity member = LoginUserInterceptor.loginUser.get();
        IPage<OrderEntity> page = this.page(new Query<OrderEntity>().getPage(params), new QueryWrapper<OrderEntity>().eq("member_id", member.getId()).orderByDesc("id"));
        List<OrderEntity> orderSn = page.getRecords().stream().map(orderEntity -> {
            List<OrderItemEntity> itemEntities = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderEntity.getOrderSn()));
            orderEntity.setItemEntities(itemEntities);
            return orderEntity;
        }).collect(Collectors.toList());
        page.setRecords(orderSn);
        PageUtils pageUtils = new PageUtils(page);
        return pageUtils;
    }
    @Override
    public String handlePayResult(PayAsyncVo payAsyncVo) {   //  payAsyncVo  是支付宝给的
        PaymentInfoEntity infoEntity = new PaymentInfoEntity();//   创建一个支付信息表

        infoEntity.setAlipayTradeNo(payAsyncVo.getTrade_no());  //  赋值

        infoEntity.setOrderSn(payAsyncVo.getOut_trade_no());  //   赋值

        infoEntity.setPaymentStatus(payAsyncVo.getTrade_status());  //   赋值

        infoEntity.setCallbackTime(payAsyncVo.getNotify_time());//    赋值

        paymentInfoService.save(infoEntity); //  保存到数据库

        if(payAsyncVo.getTrade_status().equals("TRADE_SUCCESS") ||  payAsyncVo.getTrade_status().equals("TRADE_FINISHED") ){
            String outTradeNo = payAsyncVo.getOut_trade_no();// 获取订单号
            this.baseMapper.updateOrderStatus(outTradeNo,OrderStatusEnum.PAYED.getCode());// 终于,改变订单状态了,  //(1,"已付款"),
        }
        return "success";//  告诉  支付宝  success!!
    }
    @Override
    public  OrderEntity getOrderByOrderSn(String orderSn) {
        OrderDao baseMapper1 = this.baseMapper;//public interface OrderDao extends BaseMapper<OrderEntity>
        OrderEntity orderEntity1 = baseMapper1.selectOne(new QueryWrapper<OrderEntity>().eq("order_sn", orderSn));  // 去数据库里面查询 主表 oms_order
        return orderEntity1;//  返回  一个  oms_order 对象
    }
    @Override
public void closeOrder(OrderEntity entity) {
        OrderEntity orderEntity = this.getById(entity.getId());  //  获取 订单主表对象  oms_order
        if(orderEntity.getStatus()  ==  OrderStatusEnum.CREATE_NEW.getCode()) { // CREATE_NEW(0,"待付款"),
            //   关单 ,就是说:如果等了30分钟,订单还没有支付,就关闭它
            OrderEntity update= new OrderEntity();
            update.setId(entity.getId()); //
            update.setStatus(OrderStatusEnum.CANCLED.getCode()); //  CANCLED(4,"已取消"),
            this.updateById(update);  //   更新状态
            OrderTo orderTo = new OrderTo();
            BeanUtils.copyProperties(orderEntity,orderTo);
            rabbitTemplate.convertAndSend("order-event-exchange","order.release.other",orderTo);//  这个又是什么队列？这个是库存解锁的队列
            //   关闭订单都弄好了,怎么又要发送给这个队列? 因为还要解锁库存呀!
            //  先发给交换机: order-event-exchange ,然后根据routing key:order.release.other,最后发送到队列:   stock.release.stock.queue
            // 处理的方法在 StockReleaseListener 类里面
            //
        }
    }
    //下单方法
    @Transactional
    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {
        confirmVoThreadLocal.set(vo); //给threadlocal存上订单信息
        SubmitOrderResponseVo responseVo = new SubmitOrderResponseVo();  // 包含 订单主表 和 订单是否成功码
        MemberEntity member = LoginUserInterceptor.loginUser.get();  // 获取用户信息
        responseVo.setCode(0);  // 这个是什么code?
        String   script="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        String orderToken = vo.getOrderToken();  //  获取用户前端页面传过来的token
        //  原子 验证令牌  和 删除令牌
        String keyOf_TokeFromRedis = OrderConstant.USER_ORDER_TOKEN_PREFIX + member.getId();//order:token:
        List<String>  onlyOneElementList= Arrays.asList(keyOf_TokeFromRedis);
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);  //  原子性操作
        Long result = stringRedisTemplate.execute(redisScript, onlyOneElementList, orderToken);
        if(result ==0L) {
            //  令牌验证失败
            responseVo.setCode(1);
            return responseVo;
        }else{
            //令牌验证成功
            //  下单     去 创建订单,验令牌,验价格,锁库存
            OrderCreateTo order = createOrder();  //  调用创建订单方法,返回一个小票对象.
            BigDecimal payAmount = order.getOrder().getPayAmount();  // 提取应付总额,后端计算出的数据.
            BigDecimal payPrice = vo.getPayPrice(); // 提取应付总额,用户前端提交的数据
            if(Math.abs(payAmount.subtract(payPrice).doubleValue())<0.01){ //  验证价格.  就是前端提交的要和后端计算出的保持一致
                saveOrder(order);//  保存订单 ,到这里,只是给数据库保存上数据了,但是用户还没有付钱
                //库存锁定,只要有异常,回滚订单数据
                WareSkuLockVo wareSkuLockVo = new WareSkuLockVo(); // String  orderSn;订单编号   List<OrderItemVo> locks;订单项
                wareSkuLockVo.setOrderSn(order.getOrder().getOrderSn());  //  设置订单编号
                List<OrderItemVo> orderItemVos= order.getOrderItems().stream().map(one -> {
                    OrderItemVo itemVo = new OrderItemVo();
                    itemVo.setSkuId(one.getSkuId());
                    itemVo.setCount(one.getSkuQuantity());
                    itemVo.setTitle(one.getSkuName());
                    return itemVo;
                }).collect(Collectors.toList());
                wareSkuLockVo.setLocks(orderItemVos);    //  设置 订单项
                R r = wmsFeignService.orderLockStock(wareSkuLockVo); //远程锁库存,库存服务拿着 wareSkuLockVo ,去锁定库存
                if(r.getCode()  ==0 ){// 说明  锁定成功了
                    responseVo.setOrder(order.getOrder());
                    rabbitTemplate.convertAndSend("order-event-exchange","order.create.order",order.getOrder()); //  这个是什么意思?
                    //  把 订单主表 oms_order 发到了队列:
                    //  发给的队列是:    order.delay.queue ,那么,谁在监听这个队列? 回答:没有人监听这个队列.这个是一个死信队列.
                    //  这个队列的消息,死亡之后,会发送到   order-event-exchange  交换机
                    //然后order-event-exchange  交换机 会根据routing key: order.release.order  发送到 队列:  order.release.order.queue
                    //  然后有人监听这个   order.release.order.queue  队列
                return  responseVo;
                }else{
                    String  msg = (String) r.get("msg");
                    throw  new NoStockException(msg);
                }
            }else{//   验证价格,如果价格不对.就......
                responseVo.setCode(2);
                return  responseVo;
            }
        }
    }
    @Override
    public void createSeckillOrder(SeckillOrderTo seckillOrder) {
        //   保存订单信息,这里做一个简单演示
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(seckillOrder.getOrderSn());
        orderEntity.setMemberId(seckillOrder.getMemberId());
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        BigDecimal multiply = seckillOrder.getSeckillPrice().multiply(new BigDecimal("" + seckillOrder.getNum()));
        orderEntity.setPayAmount(multiply);
        this.save(orderEntity);
        OrderItemEntity orderItemEntity = new OrderItemEntity();
        orderItemEntity.setOrderSn(seckillOrder.getOrderSn());
        orderItemEntity.setRealAmount(multiply);
        orderItemEntity.setSkuQuantity(seckillOrder.getNum());
        orderItemService.save(orderItemEntity);
    }
    private void saveOrder(OrderCreateTo order) {//   保存订单的方法.
        OrderEntity orderEntity = order.getOrder();
        Date date = new Date();
        orderEntity.setModifyTime(date);
        orderEntity.setCreateTime(date);
        this.save(orderEntity);  //  保存 订单主表.
        List<OrderItemEntity> orderItems = order.getOrderItems();
        orderItemService.saveBatch(orderItems);// 保存 订单项
    }
    private OrderCreateTo createOrder(){//  创建订单方法
        OrderCreateTo orderCreateTo = new OrderCreateTo();
        String orderSn= IdWorker.getTimeId();// 创建订单编号
        OrderEntity orderEntity = buildOrder(orderSn);  //  创建 订单主表对象  oms_order表
        List<OrderItemEntity> orderItemEntities = buildOrderItems(orderSn);//   创建 这个订单 的所有  订单项,
        //计算价格相关
        computePrice(orderEntity,orderItemEntities);  //把 订单主表 oms_order 里面的属性字段,能设置的设置设置.
        orderCreateTo.setOrder(orderEntity); //orderCreateTo是小票对象. 设置小票的订单主表信息
        orderCreateTo.setOrderItems(orderItemEntities);// 设置小票的订单项信息
        return  orderCreateTo;
    }
    private void computePrice(OrderEntity orderEntity, List<OrderItemEntity> orderItemEntities) {//  根据订单和订单项,也就是说,根据整个小票信息,计算这个订单的价格
/*
   这里计计算数值,使用BigDecimal,然后先全部设置成初始值0.
 */
        BigDecimal total= new BigDecimal("0.0");    //  总价
        BigDecimal coupon= new BigDecimal("0.0");  //  优惠券减免
        BigDecimal integration= new BigDecimal("0.0");//  积分减免
        BigDecimal promotion= new BigDecimal("0.0");//  商品本身促销金额
        BigDecimal giftIntegration= new BigDecimal("0.0");//  赠送积分
        BigDecimal giftGrowth= new BigDecimal("0.0");//赠送成长值
        for (OrderItemEntity entity : orderItemEntities) {  //遍地 订单项
            coupon =coupon.add(entity.getCouponAmount());  // 累加
            integration = integration.add(entity.getIntegrationAmount()); // 累加
             promotion  =promotion.add(entity.getPromotionAmount());//累加
            total =total.add(  entity.getRealAmount());//累加
            giftIntegration= giftIntegration.add(new BigDecimal(entity.getGiftIntegration().toString()));//累加
            giftGrowth = giftGrowth.add(new BigDecimal(entity.getGiftGrowth().toString()));// 累加
        }
        orderEntity.setTotalAmount(total);  //  设置订单总额
        BigDecimal freightAmount = orderEntity.getFreightAmount();// 获取 这比订单的 运费
        BigDecimal totalWithFreightAmount = total.add(freightAmount); //把运费加到总费用里
        orderEntity.setPayAmount(totalWithFreightAmount);//   设置 总价
        orderEntity.setPromotionAmount(promotion);  //  这整笔订单 的 促销价
        orderEntity.setIntegrationAmount(integration); // 这整笔订单的    积分抵扣
        orderEntity.setCouponAmount(coupon);// 这整订单的    优惠抵扣
        orderEntity.setIntegration(giftIntegration.intValue());        //设置积分
        orderEntity.setGrowth(giftGrowth.intValue());  // 设置成长值
        orderEntity.setDeleteStatus(0);//  设置删除状态   删除状态【0->未删除；1->已删除】
    }
    private OrderEntity buildOrder(String orderSn) { // 创建 订单主表  oms_order
        MemberEntity member = LoginUserInterceptor.loginUser.get();  // 获取用户信息
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(orderSn);// 设置 订单编号
        orderEntity.setMemberId(member.getId());// 设置 用户id
        OrderSubmitVo orderSubmitVo = confirmVoThreadLocal.get();  // 从threadlocal中,获取订单确认页提交的数据
        R fare = wmsFeignService.getFare(orderSubmitVo.getAddrId());//根据收获详细地址计算运费价格
        FareVo fareResp= fare.getData(new TypeReference<FareVo>() {});//  提取 运费价格vo对象
        BigDecimal fare1 = fareResp.getFare(); // 获取运费价格
        orderEntity.setFreightAmount(fare1);  // 设置运费价格
        //设置收货人信息
        orderEntity.setReceiverCity(fareResp.getAddress().getCity());// 设置收货人城市
        orderEntity.setReceiverDetailAddress(fareResp.getAddress().getDetailAddress());//设置收获人详细地址
        orderEntity.setReceiverName(fareResp.getAddress().getName());//设置收货人名字
        orderEntity.setReceiverPhone(fareResp.getAddress().getPhone());//设置收货人手机号
        orderEntity.setReceiverPostCode(fareResp.getAddress().getPostCode());//  设置收货人所在地的邮编
        orderEntity.setReceiverProvince(fareResp.getAddress().getProvince());//设置收货人所在省份
        orderEntity.setReceiverRegion(fareResp.getAddress().getRegion());// 设置收货人所在 区县
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());     //设置订单状态
        orderEntity.setAutoConfirmDay(7);  //设置订单自动确认时间
            return  orderEntity;  // 返回订单主表对象  oms_order
    }
    /*
    构建所有订单项数据
     */
    private List<OrderItemEntity> buildOrderItems(String orderSn) {
        List<OrderItemVo> currentUserCartItems= cartFeignService.currentUserCartItems();//去redis中,获取当前用户的购物车项目信息
        if(currentUserCartItems!=null  &&  currentUserCartItems.size()>0 ){
            List<OrderItemEntity> itemEntities = currentUserCartItems.stream().map(one -> {  //  遍历用户的购物车信息
                OrderItemEntity orderItemEntity =     buildOrderItem(one);   //把每一个订单项提取成为数据库的  oms_order_item 表
                orderItemEntity.setOrderSn(orderSn);
                return orderItemEntity;
            }).collect(Collectors.toList());
            return  itemEntities;
        }
        return null;
    }
/*
构建某一个订单项
 */
    private OrderItemEntity buildOrderItem(OrderItemVo cartItem) {
        OrderItemEntity itemEntity = new OrderItemEntity(); //创建 订单项目对象  oms_order_item表
        //1.订单信息:订单号
        //2. 商品的spu信息
        Long skuId = cartItem.getSkuId();// 获取 sku_id
        R r= productFeignService.getSpuInfoBySkuId(skuId); //根据sku_id,查询所属的spu信息
        SpuInfoVo data= r.getData(new TypeReference<SpuInfoVo>() {});//提取spu信息
        itemEntity.setSpuId(data.getId());  //设置spu_id
        itemEntity.setSpuBrand(data.getBrandId().toString());//设置品牌
        itemEntity.setSpuName(data.getSpuName());//设置spu_name
        itemEntity.setCategoryId(data.getCatalogId());//设置分类
        //3.商品的sku信息
        itemEntity.setSkuId(cartItem.getSkuId());// 设置sku_id
        itemEntity.setSkuName(cartItem.getTitle());// 设置sku_name
        itemEntity.setSkuPic(cartItem.getImage());// 设置 sku_pic
        itemEntity.setSkuPrice(cartItem.getPrice());//设置 sku价格
        //StringUtils.collectionToCommaDelimitedString方法,相当于String.join(",", list);
        String skuAttr = StringUtils.collectionToCommaDelimitedString(cartItem.getSkuAttr());// 把sku的销售属性list,转成字符串        itemEntity.setSkuAttrsVals(skuAttr);// 设置销售属性
        itemEntity.setSkuQuantity(cartItem.getCount());// 设置这个购买这个sku的数量
        //4.优惠信息(不做)
        //5.积分信息
        BigDecimal singlePrice = cartItem.getPrice();//获取每个sku的单价
        String  countOfTheItem= cartItem.getCount().toString();// 获取购买这个sku的数量
        BigDecimal bigDecimalOf_countOfTheItem = new BigDecimal(countOfTheItem); //把 购买这个sku的数量 转成 BigDecimal
        BigDecimal  totalPriceOfTheItem = singlePrice.multiply(bigDecimalOf_countOfTheItem); //   计算得出 这个购物项的总价(单价*数量)
        int integerOf_totalPriceOfTheItem = totalPriceOfTheItem.intValue();//把 这个购物项的总价(单价*数量) 抹掉两位小数
        itemEntity.setGiftGrowth(integerOf_totalPriceOfTheItem);// 设置成长值.备注:用户购买的每件东西,都会增加自己的成长值,成长值是个好东西.
        itemEntity.setGiftIntegration(integerOf_totalPriceOfTheItem);//设置积分 .备注,用户每次买东西,就会被送积分.
        //6.订单项的价格信息
        itemEntity.setPromotionAmount(new BigDecimal("0"));//  设置优惠金额,我没错优惠系统,全部设置成0
        itemEntity.setCouponAmount(new BigDecimal("0"));//  设置优惠金额,我没错优惠系统,全部设置成0
        itemEntity.setIntegrationAmount(new BigDecimal("0"));//  设置优惠金额,我没错优惠系统,全部设置成0
        Integer skuQuantity = itemEntity.getSkuQuantity();//  获取购买sku的数量
        BigDecimal bigDecimalOf_skuQuantity = BigDecimal.valueOf(skuQuantity);//  把  购买sku的数量 转成 BigDecimal
        BigDecimal skuPrice = itemEntity.getSkuPrice();
        BigDecimal originPrice_WithoutDiscount = skuPrice.multiply(bigDecimalOf_skuQuantity);  //    这是原本的价格,不使用任何优惠券的价格.
        //   这个是扣除所有减免后的价格.
        BigDecimal realPrice_WithAllDiscount = originPrice_WithoutDiscount.subtract(itemEntity.getCouponAmount()).subtract(itemEntity.getPromotionAmount()).subtract(itemEntity.getIntegrationAmount());
        itemEntity.setRealAmount(realPrice_WithAllDiscount);   //   设置 单独  购物项 的最终价格,注意,这不是整个订单最后的价格.
        return  itemEntity;
    }
}